package Function;

import FCRendering.FCRBattleOrderConstant;
import FCRendering.FCRMaster;
import Frame.battleanimation.*;
import Function.monsterattack.FCMonsterAttackCenter;
import VWorldGameStudio.*;

import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;

import static FCRendering.FCRMaster.*;

/**
 * 战斗产生战斗指令和消费指令的地方
 */
public class FCMonsterBattleOrderHelper {


    /**
     * 怪物产生Order的地方
     *
     * @param monster
     * @return
     */
    public FCBattleOrder createMonsterAttackOrder(FCMonster monster, int numCode) {
        //TODO 找一些未死的角色打，这里可以做大量的选角色策略
        FCBattleOrder ordert = FCMonsterAttackCenter.getIn().getBattleOrderByMonster(monster, numCode);
        if (ordert == null) {//默认的普通怪攻击逻辑
            ordert = new FCBattleOrder();
            FCPlayerBattleWrap wrapt = findTarget(ordert.randomV4);
            ordert.playerUid = wrapt.getHostUid();
            ordert.playerName = wrapt.getName();
            ordert.battleType = 2;
            ordert.monsterNum = numCode;
            int speed = monster.getLongTermVal(FCRBattleOrderConstant.S_AddSpeed);
            speed = speed == -1 ? 0 : speed;
            ordert.battleSpeed = monster.getSpeed() + speed;

            if(monster.isMsInConfusion()||monster.isMsInParalysis()||monster.isMsInSleep()){
                //混乱,睡眠，麻痹中
                ordert.monsterAttackType = 7;
            }

            //TDDO 优先判断是不是要逃跑
            if (ordert.monsterAttackType != 7 && monster.getEscape() > 0 && monster.getEscape() >= ordert.randomV3) {
                //逃跑
                ordert.monsterAttackType = 5;
            }

            if (ordert.monsterAttackType != 7 && ordert.monsterAttackType != 5) {
                //TODO 选中攻击方式，4种，普通，主炮，副炮, 战斗道具
                ArrayList<Integer> attackTypes = new ArrayList<>(0);
                int allWeight = 0;
                if (monster.getGun1() != null && monster.getGun1().getDefense() != 0) {
                    attackTypes.add(1);
                    allWeight += monster.getGun1().getAttackWeight();
                }
                if (monster.getGun2() != null && monster.getGun2().getDefense() != 0) {
                    attackTypes.add(2);
                    allWeight += monster.getGun2().getAttackWeight();
                }
                if (monster.getGun3() != null && monster.getGun3().getDefense() != 0) {
                    attackTypes.add(3);
                    allWeight += monster.getGun3().getAttackWeight();
                }
                if (monster.getKeepFcItems().size() > 0) {
                    attackTypes.add(4);
                    allWeight += monster.getUseItemsWeight();
                }
                int randWeight = (int) (ordert.randomV1 * allWeight);
                //根据权重来选技能攻击
                int newAll = 0;
                for (Integer i : attackTypes) {
                    if (i == 1) {
                        newAll += monster.getGun1().getAttackWeight();
                    } else if (i == 2) {
                        newAll += monster.getGun2().getAttackWeight();
                    } else if (i == 3) {
                        newAll += monster.getGun3().getAttackWeight();
                    } else if (i == 4) {
                        newAll += monster.getUseItemsWeight();
                    }

                    if (randWeight <= newAll) {
                        ordert.monsterAttackType = i;
                        break;
                    }
                }
                if(attackTypes.size() == 0){
                    //TODO 武器全损了，只能发呆了
                    ordert.monsterAttackType = 6;
                }
                //TEST
//                if (attackTypes.contains(4)) {
//                    ordert.monsterAttackType = 4;
//                }

                if (ordert.monsterAttackType == 4) {
                    float newRand = fcv.getSingleRandom();
                    ordert.monsterUseItemIndex = Math.min(monster.getKeepFcItems().size() - 1, (int) (newRand * monster.getKeepFcItems().size()));
                    FCItem useItem = itemLib.getItemOfID(monster.getKeepFcItems().get(ordert.monsterUseItemIndex));
                    if (useItem.getType().equals("food") || useItem.getType().equals("drug")) {
                        //TODO 给队友使用顺序给
                        int findMonsterIndex = numCode;
                        for (int i = 0; i < fcv.getBattleMonster().size(); i++) {
                            FCMonster f = fcv.getBattleMonster().get(i);
                            if (!f.getIsDeath()) {
                                findMonsterIndex = i;
                                break;
                            }
                        }
                        ordert.monsterUseItemToMonsterNum = findMonsterIndex;
                    }
                }
            }
        }

        return ordert;
    }


    public static FCPlayerBattleWrap findTarget(float random) {
        ArrayList<FCPlayerBattleWrap> list = new ArrayList<>(0);
        for (FCPlayerBattleWrap w : fcv.getBattleWraps()) {
            FCPlayerInfo pl = FCMutilPlayCache.findPlayerByName(w.getHostUid(), w.getName());
            if (pl != null && !pl.isDeath()) {
                list.add(w);
            }
        }
        if (list.size() > 0) {
            int rIndex = (int) (random * list.size());
            rIndex = Math.min(list.size() - 1, rIndex);
            return list.get(rIndex);
        }
        return null;
    }

    private FCBattleOrder findTarget(FCBattleOrder order) {
        ArrayList<FCPlayerBattleWrap> list = new ArrayList<>(0);
        for (FCPlayerBattleWrap w : fcv.getBattleWraps()) {
            FCPlayerInfo pl = FCMutilPlayCache.findPlayerByName(w.getHostUid(), w.getHostUid());
            if (pl != null && !pl.isDeath()) {
                list.add(w);
            }
        }
        if (list.size() == 0) {
            return null;
        }
        int rIndex = (int) (order.randomV2*list.size());
        rIndex = Math.min(list.size() - 1, rIndex);
        FCPlayerBattleWrap wrap = list.get(rIndex);
        order.playerUid = wrap.getHostUid();
        order.playerName = wrap.getName();
        order.battleAnis = null;
        return order;
    }


    public FCBattleOrder dealMonsterBattleOrder(FCBattleOrder order, int frames) {
        FCMonster monster = fcv.getBattleMonster().get(order.monsterNum);
        if (monster.getIsDeath()) {
            //已经死了无法操作,丢掉当前的指令
            giveUpTheOrder();
            return null;
        }

        if (monster.isMsInConfusion()) {
            //混乱无法操作,丢掉当前的指令
            giveUpTheOrder();
            fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 混乱了");
            fcv.showMessage();
            fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 混乱了");
            return null;
        }
        if (monster.isMsInSleep()) {
            //混乱无法操作,丢掉当前的指令
            giveUpTheOrder();
            fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 睡眠了");
            fcv.showMessage();
            fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 睡眠了");
            return null;
        }
        if (monster.isMsInParalysis()) {
            //混乱无法操作,丢掉当前的指令
            giveUpTheOrder();
            fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 麻痹了");
            fcv.showMessage();
            fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 麻痹了");
            return null;
        }

        FCPlayerInfo pl = FCMutilPlayCache.findPlayerByName(order.playerUid, order.playerName);
        if (pl == null || pl.isDeath()) {
            //已经死了无法操作,丢掉当前的指令
            giveUpTheOrder();
            //返回一个新指令找到新的人物来打
            return findTarget(order);
        }
        if (order.battleAnis == null) {
            //TODO 怪物目前只有普通攻击，要是有其他攻击全部在这里加
            order.battleAnis = new CopyOnWriteArrayList<>();
            FCAnimation animation = null;
            ABattleAni aBattleAni = null;
            FCPlayerBattleWrap wrap = FCPlayerBattleWrap.findBattleWrapByName(order.playerUid, order.playerName);
            ArrayList<FCPlayerBattleWrap> fightTargets = null;
            int[] msStartPoint = new int[2];
            int[] targetPoint = new int[2];
            Integer[] sp = fcv.getBattleMonsterCoor().get(order.monsterNum);
            msStartPoint[0] = sp[0] + sp[2];
            msStartPoint[1] = sp[1] + sp[3] / 2;
            targetPoint[0] = wrap.getCoorX() + wrap.getW() / 2;
            targetPoint[1] = wrap.getCoorY() + wrap.getH() / 2;
            switch (order.monsterAttackType) {
                case 1://主攻

                    animation = animationLib.getAnimationOfID(monster.getGun1().getAnimationId());
                    fightTargets = FCMonsterAttackCenter.getIn()
                            .getAttackPlayerByGun(monster.getGun1(), monster, order, wrap);
                    if (fightTargets.size() == 0) {
                        targetPoint[0] = (int) (1920 * fcv.getProportion());
                    }
                    aBattleAni = FCMonsterAttackCenter.getIn().getBattleABattleAniByMsAttck(monster, monster.getGun1(), msStartPoint,targetPoint);
                    if (aBattleAni == null) {
                        if (animation == null) {
                            aBattleAni = new GunShotAni(animationLib.getAnimationOfID("MsPuGong"), monster.getName(), monster.getGun1().getName(),
                                    msStartPoint, targetPoint, false);
                        } else {
                            aBattleAni = new GunShotAni(animation, monster.getName(), monster.getGun1().getName(),
                                    msStartPoint, targetPoint, false);
                        }
                    }
                    fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+
                            " "+monster.getGun1().getName());
                    fcv.showMessage();
                    fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+
                            " "+monster.getGun1().getName());
                    break;
                case 2://副攻击
                    animation = animationLib.getAnimationOfID(monster.getGun2().getAnimationId());
                    fightTargets = FCMonsterAttackCenter.getIn()
                            .getAttackPlayerByGun(monster.getGun2(), monster, order, wrap);
                    if (fightTargets.size() == 0) {
                        targetPoint[0] = (int) (1920 * fcv.getProportion());
                    }
                    aBattleAni = FCMonsterAttackCenter.getIn().getBattleABattleAniByMsAttck(monster, monster.getGun2(),msStartPoint, targetPoint);
                    if (aBattleAni == null) {
                        if (animation == null) {
                            aBattleAni = new GunShotAni(animationLib.getAnimationOfID("MsPuGong"), monster.getName(), monster.getGun3().getName(),
                                    msStartPoint, targetPoint, false);
                        } else {
                            aBattleAni = new GunShotAni(animation, monster.getName(), monster.getGun2().getName(),
                                    msStartPoint, targetPoint, false);
                        }
                    }
                    fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+
                            " "+monster.getGun2().getName());
                    fcv.showMessage();
                    fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+
                            " "+monster.getGun2().getName());
                    break;
                case 3://特殊攻击
                    animation = animationLib.getAnimationOfID(monster.getGun3().getAnimationId());
                    fightTargets = FCMonsterAttackCenter.getIn()
                            .getAttackPlayerByGun(monster.getGun3(), monster, order, wrap);
                    if (fightTargets.size() == 0) {
                        targetPoint[0] = (int) (1920 * fcv.getProportion());
                    }
                    aBattleAni = FCMonsterAttackCenter.getIn().getBattleABattleAniByMsAttck(monster, monster.getGun3(), msStartPoint,targetPoint);
                    if (aBattleAni == null) {
                        if (animation == null) {
                            aBattleAni = new GunShotAni(animationLib.getAnimationOfID("MsPuGong"), monster.getName(), monster.getGun3().getName(),
                                    msStartPoint, targetPoint, false);
                        } else {
                            aBattleAni = new GunShotAni(animation, monster.getName(), monster.getGun3().getName(),
                                    msStartPoint, targetPoint, false);
                        }
                    }
                    fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" "+monster.getGun3().getName());
                    fcv.showMessage();
                    fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" "+monster.getGun3().getName());
                    break;
                case 4:
                    //TODO 使用战斗道具，可以是给敌人也可以给怪物自己喔
                    String fcItemName = monster.getKeepFcItems().get(order.monsterUseItemIndex);
                    if (order.monsterUseItemToMonsterNum == -1) {
                        fightTargets = FCMonsterAttackCenter.getIn()
                                .getAttackPlayerByThrow(fcItemName, monster, order, wrap);
                        if (fightTargets.size() == 0) {
                            targetPoint[0] = (int) (1920 * fcv.getProportion());
                        }
                        aBattleAni = new ThrowItemAni(fcItemName, true, wrap.getName(), msStartPoint, targetPoint, false);

                        fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+
                                " 投掷"+ itemLib.getItemOfID(fcItemName).getChName());
                        fcv.showMessage();
                        fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+
                                " 投掷"+ itemLib.getItemOfID(fcItemName).getChName());
                    } else {
                        fightTargets = new ArrayList<>(0);
                        FCMonster m = fcv.getBattleMonster().get(order.monsterUseItemToMonsterNum);
                        if(m.getIsDeath()){
                            order.monsterUseItemToMonsterNum = fcv.getBattleMonster().indexOf(monster);
                        }
                        //给同伴使用的
                        Integer[] src = fcv.getBattleMonsterCoor().get(fcv.getBattleMonster().indexOf(monster));
                        targetPoint[0] = src[0] + src[2] / 2;
                        targetPoint[1] = src[1];
                        aBattleAni = new UseToolAnimation(fcItemName, targetPoint, false);
                        fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 使用"+
                                itemLib.getItemOfID(fcItemName).getChName());
                        fcv.showMessage();
                        fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 使用"+
                                itemLib.getItemOfID(fcItemName).getChName());
                    }
                    break;
                case 5:
                    aBattleAni = new MsEscapeAni(monster);
                    break;
                case 6:
                    order.frameTimes = 20;
                    fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 武器全损了");
                    fcv.showMessage();
                    fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 武器全损了");
                    return null;
                case 7:
                    order.frameTimes = 20;
                    fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 不能动弹");
                    fcv.showMessage();
                    fcv.startBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 不能动弹");
                    return null;
            }
            order.battleAnis.add(aBattleAni);
            order.frameTimes = aBattleAni.getAllFrames();
            if (fightTargets != null) {
                aBattleAni.hitFcPlayerWrap.addAll(fightTargets);
            }
        }

        for (ABattleAni battleAni : order.battleAnis) {
            battleAni.nextFrame(frames);
        }

        return null;
    }

    //处理怪物的指令
    public FCBattleOrder dealMonsterBattleOrderEnd(FCBattleOrder order) {
        FCPlayerBattleWrap wrap = FCPlayerBattleWrap.findBattleWrapByName(order.playerUid, order.playerName);
        FCMonster monster = fcv.getBattleMonster().get(order.monsterNum);

        switch (order.monsterAttackType) {
            case 3:
                FCMonsterAttackCenter.getIn().attackToPlayerByGun(monster.getGun3(), monster, order, wrap);
                break;
            case 1://主炮
                FCMonsterAttackCenter.getIn().attackToPlayerByGun(monster.getGun1(), monster, order, wrap);
                break;
            case 2://副炮
                FCMonsterAttackCenter.getIn().attackToPlayerByGun(monster.getGun2(), monster, order, wrap);
                break;
            case 4:
                String fcItemName = monster.getKeepFcItems().get(order.monsterUseItemIndex);
                if (order.monsterUseItemToMonsterNum == -1) {
                    FCMonsterAttackCenter.getIn().attackToPlayerByThrow(fcItemName, monster, order, wrap);
                } else {
                    FCMonsterAttackCenter.getIn().addBuffToMonsterByThrow(fcItemName, monster, order, fcv.getBattleMonster().get(order.monsterUseItemToMonsterNum));
                }
                break;
            case 5:
                //逃跑了
                fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 逃走了");
                fcv.showMessage();
                monster.setEscapeState(true);
                monster.setBlood(0);
                fcv.endBattleInfo( (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 逃走了");
                break;
            case 6:
                //武器全损了
                fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" 武器全损");
                fcv.showMessage();
                break;
            case 7:
//                String btips = " 混乱了";
//                if(monster.isMsInConfusion()) {
//
//                }else if(monster.isMsInSleep()){
//                    btips = " 睡眠了";
//                }else if(monster.isMsInParalysis()){
//                    btips = " 麻痹了";
//                }
//                //混乱了
//                fcv.getMessage().add((fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName()+" "+btips);
//                fcv.showMessage();
                break;
        }
        return null;
    }

    private void giveUpTheOrder() {
        fcv.getBattleAttackOrder().pop();
        fcv.setBattleAnimationNum(0);
    }
}
